package tech.yunqian.slim.framework.aspectj;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.util.ContentCachingRequestWrapper;

import tech.yunqian.slim.framework.web.AjaxResult;
import tech.yunqian.slim.framework.web.RequestValidator;
import tech.yunqian.slim.framework.web.Response;

@Aspect
@Component
public class ValidateAspect {
    @Autowired
    RequestValidator requestValidator;

    @Pointcut("@annotation(tech.yunqian.slim.framework.aspectj.annotation.ValidateRequest)")
    public void pointCut() {
    }

    @Around("pointCut()")
    public AjaxResult doAround(ProceedingJoinPoint point) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);
        String method = wrappedRequest.getMethod().toString();
        if (method.equals("POST")) {
            String path = wrappedRequest.getServletPath();
            String schema = path + ".json";
            String body = point.getArgs()[0].toString();
            int code = requestValidator.validate(schema, body);
            if (code != RequestValidator.CODE_PASS) {
                if (code == RequestValidator.CODE_SCHEMA_NOT_LOADED) {
                    return AjaxResult.error(Response.SCHEMA_NOT_LOADED.getMessage());
                } else if (code == RequestValidator.CODE_SCHEMA_PROCESSING_ERROR) {
                    return AjaxResult.error(Response.SCHEMA_PROCESSING_ERROR.getMessage());
                } else if (code != RequestValidator.CODE_PASS) {
                    return AjaxResult.error(Response.SCHEMA_MISMATCH.getMessage());
                }
            }
        }
        return (AjaxResult)point.proceed();
    }


}
